-module(my_supervisor).
-export([start_link/2, stop/1]).
-export([init/1]).

start_link(Name, ChildSpecList) ->
    register(Name, spawn_link(my_supervisor, init, [ChildSpecList])),
    ok.

init(ChildSpecList) ->
    process_flag(trap_exit, true),
    loop(start_children(ChildSpecList)).

start_children([]) ->
    [];
start_children([{M,F,A,T,R}|ChildSpecList]) ->
    case catch(apply(M,F,A)) of
	{ok, Pid} ->
	    [{Pid, {M,F,A,T,0}} | start_children(ChildSpecList)];
	_ ->
	    start_children(ChildSpecList)
    end.

restart_child(Pid, ChildList, Reason) ->
    {value, {Pid, {M,F,A,T,R}}} = lists:keysearch(Pid, 1, ChildList),
    % 当某个进程的类型是transient并且正常退出(normal)时，不重新启动该进程；
    % 其它情况都重启该这个进程
    if 
	R >= 5 -> % 当某个进程重启次数超过5次后，把其删掉
	    lists:keydelete(Pid, 1, ChildList);
	Reason==normal, T==transient ->
	    lists:keydelete(Pid, 1, ChildList);
	true ->
	    {ok, NewPid} = apply(M, F, A),
	    [{NewPid, {M,F,A,T,R+1}} | lists:keydelete(Pid, 1, ChildList)]
    end.

loop(ChildList) ->
    receive
	{'EXIT', Pid, Reason} ->
	    NewChildList = restart_child(Pid, ChildList, Reason),
	    loop(NewChildList);
	{stop, From} ->
	    From ! {reply, terminate(ChildList)}
    end.

stop(Name) ->
    Name ! {stop, self()},
    receive {reply, Reply} -> Reply end.

terminate([{Pid,_} | ChildList]) ->
    exit(Pid, kill),
    terminate(ChildList);
terminate(_ChildList) -> 
    ok.




